﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Happy.ExtentionMethods;
using Happy.Dto.CommonModel.TreeLike;
using Happy.Domain.CommonModel.TreeLike;

namespace Happy.Query.CommonModel.TreeLike
{
    /// <summary>
    /// 扩展了<see cref="IQuerySource{T}"/>。
    /// </summary>
    public static class IQuerySourceExtentions
    {
        /// <summary>
        /// 返回指定的孩子记录。
        /// </summary>
        public static IEnumerable<T> Children<T>(this IQuerySource<T> that, Guid? id)
            where T : ITreeNodeView<Guid>
        {
            return that.Children<T, Guid>(id);
        }

        /// <summary>
        /// 返回指定的孩子记录。
        /// </summary>
        public static IEnumerable<T> Children<T, TId>(this IQuerySource<T> that, TId? id)
            where T : ITreeNodeView<TId>
            where TId : struct
        {
            QueryArgument query;

            if (id == null)
            {
                query = QueryArgument.Create(TreeNodeConstant.ParentIdPropertyName + " IS NULL", new object[] { });
            }
            else
            {
                query = QueryArgument.Create(TreeNodeConstant.ParentIdPropertyName + " = @0", new object[] { id });
            }

            return that.Fetch(query);
        }

        /// <summary>
        /// 返回指定的孩子记录。
        /// </summary>
        public static IEnumerable<T> Children<T>(this IQuerySource<T> that, QueryArgument query, Guid? id)
            where T : ITreeNodeView<Guid>
        {
            return that.Children<T, Guid>(query, id);
        }

        /// <summary>
        /// 返回指定的孩子记录。
        /// </summary>
        public static IEnumerable<T> Children<T, TId>(this IQuerySource<T> that, QueryArgument query, TId? id)
            where T : ITreeNodeView<TId>
            where TId : struct
        {
            if (id == null)
            {
                query.WhereClauses.Add(WhereClause.Create(TreeNodeConstant.ParentIdPropertyName + " IS NULL", new object[] { }));
            }
            else
            {
                query.WhereClauses.Add(WhereClause.Create(TreeNodeConstant.ParentIdPropertyName + " = @0", new object[] { id }));
            }

            return that.Fetch(query);
        }

        /// <summary>
        /// 返回指定路径下的所有记录。
        /// </summary>
        public static IEnumerable<T> Descendents<T, TId>(this IQuerySource<T> that, string path, bool includeSelf)
            where T : ITreeNodeView<TId>
            where TId : struct
        {
            var searchPath = includeSelf ? (path + "%") : (path + TreeNodeConstant.NodePathSeparator + "%");

            var query = QueryArgument.Create(TreeNodeConstant.NodePathPropertyName + " LIKE @0", new object[] { searchPath });

            return that.Fetch(query);
        }
    }
}
